/*
* @Author: pardon110
* @Date: 2024-03-26 18:54:40
 * @LastEditors: pardon110@qq.com
 * @LastEditTime: 2024-03-27 11:18:02
 * @FilePath: \days7\orm\clause\clause.go

* @Description:
1）多次调用 clause.Set() 构造好每一个子句。
2）调用一次 clause.Build() 按照传入的顺序构造出最终的 SQL 语句。
构造完成后，调用 Raw().Exec() 方法执行
*/
package clause

import "strings"

// Type is the type of Clause
type Type int

// Supprot types for Clause
const (
	INSERT Type = iota
	VALUES
	SELECT
	LIMIT
	WHERE
	ORDERBY
	UPDATE
	DELETE
	COUNT
)

type Clause struct {
	sql     map[Type]string        // 子句串 xx ? xx
	sqlVars map[Type][]interface{} // 变量值  TOM
}

func (c *Clause) Set(name Type, vars ...interface{}) {
	if c.sql == nil {
		c.sql = make(map[Type]string)
		c.sqlVars = make(map[Type][]interface{})
	}
	sql, vars := generators[name](vars...)
	c.sql[name] = sql
	c.sqlVars[name] = vars
}

// 有序生成, 分成两部sql, sqlvar => statements
// Build generate  the final SQL and SQLVars
func (c *Clause) Build(orders ...Type) (string, []interface{}) {
	var sqls []string
	var vars []interface{}

	for _, order := range orders {
		if sql, ok := c.sql[order]; ok {
			sqls = append(sqls, sql)
			vars = append(vars, c.sqlVars[order]...)
		}
	}
	return strings.Join(sqls, " "), vars
}
